package com.yanqu.road.server.manger.activity;

import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.UnionActivityConditionData;
import com.yanqu.road.entity.activity.UserActivityConditionData;
import com.yanqu.road.entity.enums.eActivityType;
import com.yanqu.road.entity.enums.eBigRankType;
import com.yanqu.road.entity.player.UserInfo;
import com.yanqu.road.entity.rank.UserRank;
import com.yanqu.road.entity.task.args.UnionRiseRankArgs;
import com.yanqu.road.entity.union.UnionInfo;
import com.yanqu.road.logic.bussiness.player.UserActivityBussiness;
import com.yanqu.road.logic.bussiness.player.UserCommonActivityBussiness;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.logic.helper.ActivityHelper;
import com.yanqu.road.logic.helper.UnionActivityGroupHelper;
import com.yanqu.road.logic.rank.RankListModel;
import com.yanqu.road.logic.rank.UnionActivityRankListModel;
import com.yanqu.road.logic.rank.UnionRankMsgModel;
import com.yanqu.road.logic.rank.UnionRankMsgModelGroup;
import com.yanqu.road.pb.rank.RankProto;
import com.yanqu.road.server.GameServer;
import com.yanqu.road.server.TempMgr;
import com.yanqu.road.server.manger.cross.CrossDataMgr;
import com.yanqu.road.server.manger.player.UserMgr;
import com.yanqu.road.server.manger.rank.RankMgr;
import com.yanqu.road.server.manger.union.CrossUnionMgr;
import com.yanqu.road.server.manger.union.UnionActivityMgr;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.string.StringUtils;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class CommonActivityRankMgr extends TempMgr {

    private static Map<Integer, RankListModel> rankListModelMap;
    private static Map<Integer, RankListModel> crossRankListModelMap;

    private static Map<Integer, UnionActivityRankListModel> unionRankListModelMap;

    private static Map<Integer, Map<Long, UserActivityConditionData>> unionUserActivityDataMap;

    private static Map<Integer, Map<String, UnionActivityConditionData>> unionConditionDataMap;

    /**
     * 缓存的商会排行，不入库，数据来源于商会跨服 k=activityId
     */
    private static Map<Integer, UnionRankMsgModelGroup> unionRankMsgModelGroupMap = new ConcurrentHashMap<>();

    public static RankListModel getCrossRankListModel(int activityId) {
        return crossRankListModelMap.get(activityId);
    }

    @Override
    public boolean init() throws Exception {
        return reload();
    }

    @Override
    public boolean reloadConfig() throws Exception {
        return true;
    }

    @Override
    public boolean stop() {
        return false;
    }

    @Override
    public boolean save() {
        for (Map<String, UnionActivityConditionData> unionActivityConditionDataMap : unionConditionDataMap.values()) {
            for (UnionActivityConditionData data : unionActivityConditionDataMap.values()) {
                if (data.isInsertOption()) {
                    UserActivityBussiness.addUnionActivityConditionData(data);
                } else if (data.isUpdateOption()) {
                    UserActivityBussiness.updateUnionActivityConditionData(data);
                }
            }
        }
        return true;
    }

    @Override
    public boolean reloadData() {
        rankListModelMap = new ConcurrentHashMap<>();
        unionRankListModelMap = new ConcurrentHashMap<>();
        unionConditionDataMap = new ConcurrentHashMap<>();
        unionUserActivityDataMap = new ConcurrentHashMap<>();
        crossRankListModelMap = new ConcurrentHashMap<>();
        reloadRank();
        return true;
    }

    public static RankListModel getRankListModel(int activityId) {
        return rankListModelMap.get(activityId);
    }

    public static UnionActivityRankListModel getUnionRankListModel(int activityId) {
        return unionRankListModelMap.get(activityId);
    }

    public static void removeUnionActivityRank(int activityId, String unionUid) {
        UnionActivityRankListModel unionActivityRankListModel = getUnionActivityRankListModel(activityId);
        if (null != unionActivityRankListModel) {
            unionActivityRankListModel.removeRank(unionUid);
        }
    }

    public static int getCommonActivityRank(int activityId, long userId) {
        RankListModel rankListModel = getRankListModel(activityId);
        if (null != rankListModel) {
            return rankListModel.getMyRank(userId);
        }
        return -1;
    }

    public static int getCommonActivityUnionRank(int activityId, String unionUid) {
        UnionActivityRankListModel rankListModel = getUnionRankListModel(activityId);
        if (null != rankListModel) {
            return rankListModel.getMyRank(unionUid);
        }
        return -1;
    }

    public static void changeRank(int activityId, UserInfo userInfo, BigInteger value) {
        RankListModel rankListModel = getRankListModel(activityId);
        if (null != rankListModel) {
            UserRank userRank = rankListModel.rankChange(userInfo.getUserId(), UserMgr.parseUserBaseInfo(userInfo, GameServer.getInstance().getServerId()), value, "");
        }
        RankListModel crossModel = crossRankListModelMap.get(activityId);
        if (crossModel != null) {
            UserRank userRank = crossModel.rankChange(userInfo.getUserId(), UserMgr.parseUserBaseInfo(userInfo, GameServer.getInstance().getServerId()), value, "");
            if (null != userRank && CommonActivityMgr.isCrossCommonActivity(activityId)) {//上传到跨服
                CrossDataMgr.activityRankChange(activityId, userRank, false);
            }
        }
    }

    /**
     * 加载通用活动排行榜
     */
    public static void reloadRank() {
        List<ActivityInfo> activityInfoList = CommonActivityMgr.getAllOpenCommonActivityInfoList();
        for (ActivityInfo activityInfo : activityInfoList) {
            if (null != activityInfo) {
                synchronized (unionConditionDataMap) {
                    //个人榜
                    int rankNum;
                    if (!rankListModelMap.containsKey(activityInfo.getActivityId())) {
                        RankListModel rankListModel = new RankListModel(eBigRankType.Normal.getValue(), activityInfo.getActivityId());
                        rankNum = CommonActivityMgr.getMaxRankByType(activityInfo.getActivityId(), ActivityHelper.COMMON_ACTIVITY_CONDITION_TYPE_USER);
                        if (rankNum <= 0) {
                            rankNum = GameConfig.RANK_DEFAULT_MAX_COUNT;
                        }
                        rankListModel.setRankNum(rankNum);
                        rankListModel.setRankList(RankMgr.parseUserRankList(UserCommonActivityBussiness.getUserActivityConditionDataList(activityInfo.getActivityId(),
                                ActivityHelper.COMMON_ACTIVITY_CONDITION_TYPE_USER, rankNum), rankNum));
                        rankListModelMap.put(activityInfo.getActivityId(), rankListModel);
                    }
                    if (!crossRankListModelMap.containsKey(activityInfo.getActivityId())) {
                        if (activityInfo.getType() == eActivityType.CrossCommonActivity.getValue()) {
                            RankListModel rankListModel = new RankListModel(eBigRankType.Normal.getValue(), activityInfo.getActivityId());
                            rankNum = CommonActivityMgr.getMaxRankByType(activityInfo.getActivityId(), ActivityHelper.COMMON_ACTIVITY_CONDITION_TYPE_CROSS);
                            if (rankNum <= 0) {
                                rankNum = GameConfig.RANK_DEFAULT_MAX_COUNT;
                            }
                            rankListModel.setRankNum(rankNum);
                            rankListModel.setRankList(RankMgr.parseUserRankList(UserCommonActivityBussiness.getUserActivityConditionDataList(activityInfo.getActivityId(),
                                    ActivityHelper.COMMON_ACTIVITY_CONDITION_TYPE_CROSS, rankNum), rankNum));
                            crossRankListModelMap.put(activityInfo.getActivityId(), rankListModel);
                        }
                    }
                    //商会榜
                    if (activityInfo.getType() == eActivityType.CommonActivity.getValue()) {
                        if (!unionRankListModelMap.containsKey(activityInfo.getActivityId())) {
                            Map<Long, UserActivityConditionData> tempUserConditionDataMap = UserCommonActivityBussiness.getUserActivityConditionDataMap(activityInfo.getActivityId(),
                                    ActivityHelper.COMMON_ACTIVITY_CONDITION_TYPE_UNION);
                            Map<String, UnionActivityConditionData> tempUnionConditionDataMap = UserActivityBussiness.getUnionActivityConditionDataMap(activityInfo.getActivityId());
                            UnionActivityMgr.checkUnionActivityConditionData(tempUserConditionDataMap, tempUnionConditionDataMap);
                            unionConditionDataMap.put(activityInfo.getActivityId(), tempUnionConditionDataMap);
                            unionUserActivityDataMap.put(activityInfo.getActivityId(), tempUserConditionDataMap);
                            UnionActivityRankListModel unionRankListModel = new UnionActivityRankListModel(activityInfo.getActivityId());
                            rankNum = CommonActivityMgr.getMaxRankByType(activityInfo.getActivityId(), ActivityHelper.COMMON_ACTIVITY_CONDITION_TYPE_UNION);
                            if (rankNum <= 0) {
                                rankNum = GameConfig.RANK_DEFAULT_MAX_COUNT;
                            }
                            unionRankListModel.setRankNum(rankNum);
                            unionRankListModel.initRankList(tempUnionConditionDataMap);
                            unionRankListModelMap.put(activityInfo.getActivityId(), unionRankListModel);
                        }
                    }
                }
            }
        }
    }

    public static void changeUnionActivityValue(int activityId, String unionUid, long userId, UserActivityConditionData userConditionData, int notifyType) {
        UnionInfo unionInfo = CrossUnionMgr.getUnionInfo(unionUid);

        ActivityInfo inTimeActivityInfo = CommonActivityMgr.getInTimeCommonActivityInfo(activityId);
        //属于活动开始和结束时间
        if (null != inTimeActivityInfo && activityId == inTimeActivityInfo.getActivityId()) {
            if (null != unionInfo && !unionInfo.isDelete()) {
                checkUnionConditionData(activityId, unionUid);
                UnionActivityConditionData unionActivityConditionData;
                synchronized (unionConditionDataMap) {
                    unionActivityConditionData = UnionActivityMgr.changeUnionActivityConditionData(activityId, unionUid, unionInfo, unionConditionDataMap);
                    if (UnionRiseRankArgs.NOTIFY_TYPE_NORMAL == notifyType || UnionRiseRankArgs.NOTIFY_TYPE_JOIN == notifyType) {
                        if (null != userConditionData) {
                            unionActivityConditionData.addMemberUserId(userConditionData.getUserId());
                            setUserActivityConditionData(userConditionData);
                        }
                    } else if (UnionRiseRankArgs.NOTIFY_TYPE_REMOVE == notifyType || UnionRiseRankArgs.NOTIFY_TYPE_DELETE == notifyType) {
                        unionActivityConditionData.removeMemberUserId(userId);
                        unionActivityConditionData.removeMemberPosition(userId);
                    } else if (UnionRiseRankArgs.NOTIFY_TYPE_POSITION_CHANGE == notifyType) {
                    }
                    UnionActivityMgr.changeUnionMemberPositionData(unionUid, userId, unionActivityConditionData);
                    UnionActivityMgr.calcUnionActivityConditionValue(unionActivityConditionData, getUserActivityConditionDataMap(activityId));
                }
                UnionActivityRankListModel unionActivityRankListModel = getUnionActivityRankListModel(activityId);
                if (null != unionActivityRankListModel) {
                    if (unionActivityConditionData.getMemberUserCount() > 0) {
                        unionActivityRankListModel.rankChange(unionActivityConditionData);
                    } else {
                        unionActivityRankListModel.removeRank(unionUid);
                    }
                }
            }else {
                synchronized (unionConditionDataMap) {
                    UnionActivityConditionData  unionActivityConditionData = UnionActivityMgr.changeUnionActivityConditionData(activityId, unionUid, unionInfo, unionConditionDataMap);
                    if (unionActivityConditionData != null) {
                        unionActivityConditionData.setValue(BigInteger.ZERO);
                        unionActivityConditionData.setMemberUserIdList(new ArrayList<>());
                        unionActivityConditionData.setMemberPositionMap(new HashMap<>());
                    }
                    UnionActivityRankListModel unionActivityRankListModel = getUnionActivityRankListModel(activityId);
                    unionActivityRankListModel.removeRank(unionUid);
                }
            }
        }
    }

    public static UnionActivityRankListModel getUnionActivityRankListModel(Integer activityId) {
        return unionRankListModelMap.get(activityId);
    }

    public static Map<Long, UserActivityConditionData> getUserActivityConditionDataMap(int activityId) {
        return unionUserActivityDataMap.get(activityId);
    }

    public static UserActivityConditionData getUserActivityConditionData(int activityId, long userId) {
        Map<Long, UserActivityConditionData> dataMap = getUserActivityConditionDataMap(activityId);
        if (null != dataMap) {
            return dataMap.get(userId);
        }
        return null;
    }

    public static void setUserActivityConditionData(UserActivityConditionData userActivityConditionData) {
        if (null == userActivityConditionData) {
            return;
        }
        checkUnionUserConditionData(userActivityConditionData.getActivityId());
        Map<Long, UserActivityConditionData> dataMap = getUserActivityConditionDataMap(userActivityConditionData.getActivityId());
        if (null != dataMap) {
            dataMap.put(userActivityConditionData.getUserId(), userActivityConditionData);
        }
    }

    public static UnionActivityConditionData getUnionActivityConditionData(int activityId, String unionUid) {
        Map<String, UnionActivityConditionData> dataMap = getUnionActivityConditionDataMap(activityId);
        if (null != dataMap) {
            return dataMap.get(unionUid);
        }
        return null;
    }

    public static Map<String, UnionActivityConditionData> getUnionActivityConditionDataMap(int activityId) {
        return unionConditionDataMap.get(activityId);
    }

    public static UnionActivityConditionData getUnionActivityConditionData(int activityId, long userId) {
        Map<String, UnionActivityConditionData> dataMap = getUnionActivityConditionDataMap(activityId);
        if (null != dataMap) {
            for (UnionActivityConditionData unionActivityConditionData : dataMap.values()) {
                if (unionActivityConditionData.hasMemberUserId(userId)) {
                    return unionActivityConditionData;
                }
            }
        }
        return null;
    }

    private static void checkUnionUserConditionData(int activityId) {
        if (!unionUserActivityDataMap.containsKey(activityId)) {
            synchronized (unionUserActivityDataMap) {
                if (!unionUserActivityDataMap.containsKey(activityId)) {
                    unionUserActivityDataMap.put(activityId, new ConcurrentHashMap<>());
                }
            }
        }
    }

    private static void checkUnionConditionData(int activityId, String unionUid) {
        if (!StringUtils.isNullOrEmpty(unionUid)) {
            if (!unionConditionDataMap.containsKey(activityId)) {
                synchronized (unionConditionDataMap) {
                    if (!unionConditionDataMap.containsKey(activityId)) {
                        unionConditionDataMap.put(activityId, new ConcurrentHashMap<>());
                    }
                }
            }
        }
    }

    public static UnionRankMsgModel getUnionRankMsgModel(int activityId) {
        return getUnionRankMsgModelByGroup(activityId, UnionActivityGroupHelper.NO_NEED_GROUP_ID);
    }

    public static UnionRankMsgModel getUnionRankMsgModelByGroup(int activityId, int groupId) {
        ActivityInfo activityInfo = ActivityMgr.getOpenActivityInfo(activityId);
        if (null == activityInfo) {
            return null;
        }
        UnionRankMsgModelGroup modelGroup = unionRankMsgModelGroupMap.get(activityId);
        if (modelGroup == null) {
            synchronized (unionRankMsgModelGroupMap) {
                modelGroup = unionRankMsgModelGroupMap.get(activityId);
                if (modelGroup == null) {
                    modelGroup = new UnionRankMsgModelGroup(activityId, activityInfo.getEndShowTime());
                    unionRankMsgModelGroupMap.put(activityId, modelGroup);
                }
            }
        }
        UnionRankMsgModel model = modelGroup.getUnionRankMsgModel(groupId);
        return model;
    }

    public static void checkUnionRankMsgOver() {
        List<Integer> removeActivityId = new ArrayList<>();
        long now = DateHelper.getCurrentSecond();
        synchronized (unionRankMsgModelGroupMap) {
            for (UnionRankMsgModelGroup modelGroup : unionRankMsgModelGroupMap.values()) {
                if (now >= modelGroup.getEndTime()) {
                    removeActivityId.add(modelGroup.getActivityId());
                }
            }
        }

        if (!removeActivityId.isEmpty()) {
            synchronized (unionRankMsgModelGroupMap) {
                for (Integer activityId : removeActivityId) {
                    unionRankMsgModelGroupMap.remove(activityId);
                }
            }
        }
    }
}
